#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：api_testing 
@File    ：request_control.py
@IDE     ：PyCharm 
@Author  ：future76
@Date    ：2024/7/5 15:26 
@Desc    ：处理request请求前后的用例数据
"""
# 标准库导入
import json
# 第三方库导入
import allure
from loguru import logger
from requests import request
# 本地应用/模块导入
from common.path_config import CASEDATADIR, ENV
from utils.data_utils.extract_data_handle import convert_to_dict, switch_case
from utils.files_utils.excel_handle import ExcelHandle
from utils.requests_utils.url_utils import get_base_url, is_valid_url


def get_test_data():
    """获取测试数据"""
    # 根据配置文件读取指定数据
    target, appoint_file=switch_case()
    AllCaseData = ExcelHandle.multifile_excel(target=target,appoint_file=appoint_file)
    return [(file_name, case) for file_name, cases in AllCaseData.items() for case in cases]


def request_data(CaseData:dict):
    """请求数据处理"""

    data = {}
    try:
        # 请求方式 method
        data["method"] = CaseData["method"] if isinstance(CaseData["method"], str) else None
        # url
        if is_valid_url(CaseData["path"]):
            data["url"] = CaseData["path"]
        else:
            data["url"] = get_base_url(ENV) + CaseData["path"]
        # 参数类型
        data["type"] = CaseData["type"] if isinstance(CaseData["type"], str) else None
        # 请求头headers
        data["headers"] = eval(CaseData["headers"]) if isinstance(CaseData["headers"], str) else None
        # 请求体
        # 增加对excel文件中请求体中的null处理
        if CaseData["type"] == "json":
            data["payload"] = json.loads(CaseData["payload"]) if isinstance(CaseData["payload"], str) else None
            # data["payload"] = json.dumps(data["payload"])
        elif CaseData["type"] == "params" and CaseData["method"] == "get" and isinstance(CaseData["payload"], str):
            data["payload"] = convert_to_dict(CaseData["payload"])
        else:
            data["payload"] = eval(CaseData["payload"]) if isinstance(CaseData["payload"], str) else None
    except json.JSONDecodeError as e:
        logger.error(f"数据解析错误：{e}")
        raise
    return data


def send_api_request(data:dict):
    """
    发送API请求

    :param data: 请求的数据  {'method': 'get', 'url': 'https://gzj.qianxuncc.cn/static/js/app.b8dcea1f.js','headers': None, 'payload': {'cacheStamp': '1720400210973'}}
    :return: 响应
    """
    method = data.get("method")
    url = data.get("url")
    request_type = data.get("type").lower() if data.get("type") else None
    headers = data.get("headers")
    payload = data.get("payload")
    logger.info(f"\n======================================================\n"
                 "-------------发送请求--------------------\n"
                 f"请求URL: {url}\n"
                 f"请求方式: {method}\n"
                 f"请求头:   {headers}\n"
                 f"请求关键字: {request_type}\n"
                 f"请求参数: {payload}\n"
                 "=====================================================")
    # TODO 文件上传的后续优化补充
    if payload and request_type in ["params", "json", "data", "file"]:
        # 使用参数字段替换payload
        data[request_type] = data.pop("payload")
    # 如果请求体中没有请求类型和请求参数
    elif request_type is None and payload is None:
        data["data"] = data.pop("payload")
    # 删除type字段
    data.pop("type")
    # allure报告记录请求体
    attach_request_details(**data)
    # 发送请求
    response = request(**data)
    return response


def attach_request_details(**data):
    """allure报告请求详情"""
    method,url,headers, body = data.values()
    with allure.step(f'发送{method}请求'):
        # 请求方式
        allure.attach(f'method: {method}', name='请求方式', attachment_type=allure.attachment_type.TEXT)
        # url
        allure.attach(f'url: {url}', name='url', attachment_type=allure.attachment_type.TEXT)
        # Headers
        allure.attach(json.dumps(headers, indent=2), name='请求头 Headers', attachment_type=allure.attachment_type.JSON)
        # 请求参数
        allure.attach(json.dumps(body, indent=2), name='请求参数', attachment_type=allure.attachment_type.JSON)


def record_test_result(CaseData, file_name, value):
    """记录测试结果到 Excel"""
    # 获取指定字段在文件中的行和列
    row, column = ExcelHandle.field_location(CaseData, "result")
    # 调用写入的方法
    ExcelHandle.multifile_excel(appoint_file=file_name, row=row, column=column, value=value, mode="w")


if __name__ == '__main__':
    # print(get_test_data())
    # data = {'id': 1, 'featureName': 'F01_用户管理', 'caseName': '成功调用登陆接口，message返回success', 'path': 'uaa/login/acct', 'method': 'post', 'headers': None, 'type': 'data', 'payload': '{\n        "clientId": "83YslrcMpBt3X3c0eK8jvhdPAW84ScHc",\n        "clientSecret": "rosJtPuAMy69wnEMiw9UqRaQNELypEyk",\n        "loginIp": "113.240.251.66",\n        "username": \'19918899808\',\n        "password": \'@Qxun5*27%5g\',\n        "phoneLogin": "0"\n    }', 'assertType': 'eq', 'actualJsonpath': 'code', 'expectData': 0, 'result': '测试通过，断言成功。', 'jsonExData': '{"VAR_TOKEN":"$..data.value","MSG":"$.message"}', 'is_true': True}
    # data = {'id': 3, 'featureName': 'F01_视频号列表', 'caseName': '在线状态为在线', 'path': 'jingtun-no-manage/videoAccInfo/pageListVideoWxAccInfo', 'method': 'post', 'headers': '{"Content-Type":"application/json",\n"Authorization":  "Bearer cee8cc90-e52e-4e7d-b280-9149baaa37e3","Isyou":"FBE83B15700907E056A5C7ECDF73D0A5+-=,1F26A3D1F4D6C1EF1D06046E80D1F6CE+-="}', 'type': 'json', 'payload': '{"groupId":0,"businessType":"","limit":10,"page":1,"isClose":"","isOnline":"1","isCanceled":"","isOpenVideo":"","uniqueType":"3","uniqueParam":[],"startRecycleTime":"","endRecycleTime":"","startCloseTime":"","endCloseTime":"","openStartTime":"","openEndTime":"","startExpireTime":"","endExpireTime":"","sourceType":"","isHaveShopCar":"","isCompliance":"","isHaveHeating":"","isGoodHaveHeating":"","isAllot":"","startPostVideoCount":"","endPostVideoCount":"","startFansCount":"","endFansCount":"","isRecycle":"","enabled":"","merchantType":"","merchantId":"","hyMerchantId":"","wxProtocolType":"","personalityEditInfo":[],"majorViolation":{"end":"","start":""},"minorViolation":{"end":"","start":""},"visionBottoms":[],"smallVersions":[],"bigVersion":[],"region":"","osVersion":"","reportStatus":"","platMerchantNoList":[],"nickNameLike":"","industryId":"","isThousandFans":"","isRealName":"","isRaising":"","isTruthVerify":"","openTimeAfter":"","isExpired":"","isLimit":""}', 'assertType': 'one_to_many', 'actualJsonpath': 'wxIsOnline', 'expectData': 1, 'result': '测试通过，断言成功。', 'jsonExData': None, 'is_true': True}
    data = {'id': 4, 'featureName': 111111, 'caseName': 11112222, 'path': 'https://gzj.qianxuncc.cn/static/js/app.b8dcea1f.js', 'method': 'get', 'headers': None, 'type': 'params', 'payload': "cacheStamp=1720400210973", 'assertType': None, 'actualJsonpath': None, 'expectData': None, 'result': None, 'jsonExData': None, 'is_true': True}
    print(request_data(data))
    aaa = {'method': 'get', 'url': 'https://gzj.qianxuncc.cn/static/js/app.b8dcea1f.js','headers': None, 'payload': {'cacheStamp': '1720400210973'}}
    attach_request_details(**aaa)
    # print(send_api_request(request_data(data)).text)
    # params = {'cacheStamp':1720400210973}
    # url = "https://gzj.qianxuncc.cn/static/js/app.b8dcea1f.js"
    # print(request("get", url, params=params).text)







